import * as FileSystem from "expo-file-system";
import {USER_DATA_SAVE_PATH_PREFIX} from "@/constants/storage";
import {getFileExtension} from "@/utils/file-utils";
import {
    ChatUserProfileType,
    ChatUserProfileUpdateType,
} from "@/types/user-profile";
import getSqliteClient from "@/services/sqlite/init";

const client = getSqliteClient();

function mapToUserProfile(row: any): ChatUserProfileType {
    return {
        id: row.id,
        name: row.name,
        avatar: row.avatar,
        updateTime: row.update_time,
    };
}

export async function insertUserProfile(profile: ChatUserProfileType) {
    let avatarPath = null;

    if (profile.avatar) {
        const dir = `${FileSystem.documentDirectory}${USER_DATA_SAVE_PATH_PREFIX}${profile.id}`;
        await FileSystem.makeDirectoryAsync(dir, {intermediates: true});
        const ext = getFileExtension(profile.avatar);
        const fileName = `avatar.${ext}`;
        avatarPath = `${dir}/${fileName}`;
        await FileSystem.downloadAsync(profile.avatar, avatarPath);
        profile.avatar = avatarPath;
    }

    await client.runAsync(
        `INSERT INTO chat_user (id, name, avatar, update_time) VALUES (?, ?, ?, ?)`,
        [
            profile.id,
            profile.name,
            profile.avatar,
            profile.updateTime,
        ]
    );
}

export async function deleteUserProfileById(id: string) {
    // 删除用户数据文件夹
    const dir = `${FileSystem.documentDirectory}${USER_DATA_SAVE_PATH_PREFIX}${id}`;
    try {
        await FileSystem.deleteAsync(dir, {idempotent: true});
    } catch (e) {
        console.error(e);
    }
    await client.runAsync(`DELETE FROM chat_user WHERE id = ?`, [id]);
}

export async function getUserProfileById(
    id: string
): Promise<ChatUserProfileType | null> {
    const res = await client.getFirstAsync(
        `SELECT * FROM chat_user WHERE id = ?`,
        [id]
    );
    return res && mapToUserProfile(res);
}

export async function updateUserProfile(
    oldProfile: ChatUserProfileType | null,
    data: ChatUserProfileUpdateType
) {
    let avatarPath: string | undefined;
    if (data.avatar) {
        if (oldProfile && oldProfile.avatar) {
            try {
                await FileSystem.deleteAsync(oldProfile.avatar, {idempotent: true});
            } catch (e) {
                // 忽略删除失败
            }
        }
        // 保存新头像
        const dir = `${FileSystem.documentDirectory}${USER_DATA_SAVE_PATH_PREFIX}${data.id}`;
        await FileSystem.makeDirectoryAsync(dir, {intermediates: true});
        const ext = getFileExtension(data.avatar);
        const fileName = `avatar.${ext}`;
        avatarPath = `${dir}/${fileName}`;
        await FileSystem.downloadAsync(data.avatar, avatarPath);
        data.avatar = avatarPath;
    }

    const fields = [];
    const values = [];
    for (const key in data) {
        if (key === "updateTime") fields.push("update_time = ?");
        else fields.push(`${key} = ?`);
        values.push((data as any)[key]);
    }
    if (fields.length === 0) return;
    values.push(data.id);
    await client.runAsync(
        `UPDATE chat_user SET ${fields.join(", ")} WHERE id = ?`,
        values
    );
}
